#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QFileDialog>
#include <QImage>
#include <QPainter>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->widget->setAlignment(Qt::AlignTop | Qt::AlignLeft);
    connect(ui->widget,SIGNAL(getPointForLine(QPoint*,QPoint*)),this,SLOT(drawLine(QPoint*,QPoint*)));
    connect(ui->widget,SIGNAL(getPointForBezier(QPoint*,QPoint*,QPoint*,QPoint*)),this,SLOT(drawCubicBezier(QPoint*,QPoint*,QPoint*,QPoint*)));
    connect(ui->widget,SIGNAL(clearMyScreen()),this,SLOT(on_pushButton_7_clicked()));
    connect(ui->widget,SIGNAL(clearMySelection()),this,SLOT(on_pushButton_2_clicked()));
    myScene=new sceneSubClass();
    ui->widget->setScene(myScene);

    noOfLines=0;
    noOfBeziers=0;
    delCount=0;
    fontFileName="arial.ttf";
    ui->statusBar->setVisible(true);
//    ui->statusBar->setStatusTip("hhello...............");

    ui->statusBar->showMessage("kgnjkjkgkbg",5000);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::rect_moved_useful_2(qreal xCord, qreal yCord, int index, int pathNo, int pathType)
{
    qDebug()<<"rect_moved_useful_2"<<"index:"<<index<<"pathNo:"<<pathNo<<"pathType"<<pathType;
    redrawControlPoints(xCord,yCord,index,pathNo,pathType);
}

//void MainWindow::orphan_rect_moved_useful_2(qreal xCord, qreal yCord, int pathNo, int pathType, QPointF myPos)
//{
//    qDebug()<<"orphan_rect_moved_useful_2";
//    orphan_redrawControlPoints(xCord,yCord,pathNo,pathType,myPos);
//}

void MainWindow::drawLine(QPoint *p0, QPoint *p1)
{
    qDebug()<<"in draw line slot : "<<p0->x()<<" "<<p1->x();
    QPoint *t1=new QPoint(*p0);
    QPoint *t2=new QPoint(*p1);
    lineDrawing(t1, t2, 1,999,3);
    //item no 999 is for new item coz it is ignored so can be any number
}

void MainWindow::drawRect(QPoint *p0, QPoint *p1)
{
     qDebug()<<"in draw rect slot : "<<p0->x()<<" "<<p1->x();
     QPoint *t1=new QPoint(*p0);
     QPoint *t2=new QPoint(*p1);
     rectDrawing(t1,t2);
}

void MainWindow::drawCubicBezier(QPoint *p0, QPoint *p1, QPoint *p2, QPoint *p3)
{
    qDebug()<<"in draw bzr slot";
    QPoint *t1=new QPoint(*p0);
    QPoint *t2=new QPoint(*p1);
    QPoint *t3=new QPoint(*p2);
    QPoint *t4=new QPoint(*p3);
    bezierDrawing(t1,t2,t3,t4,1,4,999);
    //item no 999 is for new item coz it is ignored so can be any number
}

void MainWindow::slot_addRectsToScene(int myNo, int myType)
{
    if(myType==1)
    {
        qDebug()<<"slot_addRectsToScene : myType==1"<<" pathno: "<<myNo;
        pathSubClass *tempItem=LinePathItems.value(myNo);
        myScene->addItem(tempItem->getRectfromMap(1));
        myScene->addItem(tempItem->getRectfromMap(2));
        qDebug()<<tempItem->getRectfromMap(1)->getMyParentPathType();
        qDebug()<<tempItem->getRectfromMap(2)->getMyParentPathType();
    }
    else if(myType==2)
    {
        qDebug()<<"slot_addRectsToScene : myType==2"<<" pathno: "<<myNo;
        pathSubClass *tempItem=curvePathItems.value(myNo);
        myScene->addItem(tempItem->getRectfromMap(1));
        myScene->addItem(tempItem->getRectfromMap(4));
    }
   else if(myType==3)
    {
        qDebug()<<"slot_addRectsToScene : myType==3"<<" pathno: "<<myNo;
        pathSubClass *tempItem=orp_LineItems.value(myNo);
        myScene->addItem(tempItem->getRectfromMap(1));
        myScene->addItem(tempItem->getRectfromMap(2));
    }
    else if(myType==4)
    {
        qDebug()<<"slot_addRectsToScene : myType==4"<<" pathno: "<<myNo;
        pathSubClass *tempItem=orp_BezierItems.value(myNo);
        myScene->addItem(tempItem->getRectfromMap(1));
        myScene->addItem(tempItem->getRectfromMap(4));
    }
}

void MainWindow::slot_removeRectsFromScene(int myNo, int myType)
{
    if(myType==1)
    {
        qDebug()<<"slot_removeRectsFromScene : myType==1"<<" pathno "<<myNo;
        pathSubClass *tempItem=LinePathItems.value(myNo);
        myScene->removeItem(tempItem->getRectfromMap(1));
        myScene->removeItem(tempItem->getRectfromMap(2));
    }
    else if(myType==2)
    {
        qDebug()<<"slot_removeRectsFromScene : myType==2"<<" pathno "<<myNo;
        pathSubClass *tempItem=curvePathItems.value(myNo);
        myScene->removeItem(tempItem->getRectfromMap(1));
        myScene->removeItem(tempItem->getRectfromMap(4));
    }
    else if(myType==3)
    {
        qDebug()<<"slot_removeRectsFromScene : myType==3"<<" pathno "<<myNo;
         pathSubClass *tempItem=orp_LineItems.value(myNo);
         myScene->removeItem(tempItem->getRectfromMap(1));
         myScene->removeItem(tempItem->getRectfromMap(2));
    }
    else if(myType==4)
    {
        qDebug()<<"slot_removeRectsFromScene : myType==4"<<" pathno "<<myNo;
        pathSubClass *tempItem=orp_BezierItems.value(myNo);
        myScene->removeItem(tempItem->getRectfromMap(1));
        myScene->removeItem(tempItem->getRectfromMap(4));
    }
}

void MainWindow::slot_addControlRectsToScene(int myNo, int myType)
{
   if(myType==2)
    {
        qDebug()<<"slot_addRectsToScene : myType==2"<<" pathno: "<<myNo;
        pathSubClass *tempItem=curvePathItems.value(myNo);
        myScene->addItem(tempItem->getRectfromMap(2));
        myScene->addItem(tempItem->getRectfromMap(3));
    }
    else if(myType==4)
    {
        qDebug()<<"slot_addRectsToScene : myType==4"<<" pathno: "<<myNo;
        pathSubClass *tempItem=orp_BezierItems.value(myNo);
        myScene->addItem(tempItem->getRectfromMap(2));
        myScene->addItem(tempItem->getRectfromMap(3));
    }
}

void MainWindow::slot_removeControlRectsFromScene(int myNo, int myType)
{
    if(myType==2)
    {
        qDebug()<<"slot_removeRectsFromScene : myType==2"<<" pathno "<<myNo;
        pathSubClass *tempItem=curvePathItems.value(myNo);
        myScene->removeItem(tempItem->getRectfromMap(2));
        myScene->removeItem(tempItem->getRectfromMap(3));
    }
    else if(myType==4)
    {
        qDebug()<<"slot_removeRectsFromScene : myType==4"<<" pathno "<<myNo;
        pathSubClass *tempItem=orp_BezierItems.value(myNo);
        myScene->removeItem(tempItem->getRectfromMap(2));
        myScene->removeItem(tempItem->getRectfromMap(3));
    }
}

void MainWindow::lineDrawing(QPoint *p0, QPoint *p1, int lineStatus,int itemNo, int pathType)
{

    QPointF *point0=new QPointF(*p0);
    QPointF *point1=new QPointF(*p1);
    QPainterPath *path1=new QPainterPath;
    path1->moveTo(*point0);
    path1->lineTo(*point1);
    if(lineStatus==1)
    {
        noOfLines++;
        myLineItem=new pathSubClass(*path1,noOfLines,pathType);
    }
    if(lineStatus==2)
    {
        qDebug()<<"lineStatus==2";
        myLineItem=new pathSubClass(*path1,itemNo,pathType);
    }
    connect(myLineItem,SIGNAL(addRectsToScene(int,int)),this,SLOT(slot_addRectsToScene(int,int)));
    connect(myLineItem,SIGNAL(removeRectsFromScene(int,int)),this,SLOT(slot_removeRectsFromScene(int,int)));

//    if(lineStatus == 1)
//        myLineItem->setPen(QPen(QColor(Qt::red),3));
//    else if(lineStatus == 2)
//        myLineItem->setPen(QPen(QColor(Qt::blue),3));
    rectSubClass *rect1, *rect2;
    if(lineStatus==1 && pathType==3)
    {
        rect1=new rectSubClass(1,noOfLines,3);
        rect2=new rectSubClass(2,noOfLines,3);
    }
    else if(lineStatus==2 && pathType==3)
    {
        rect1=new rectSubClass(1,itemNo,3);

        rect2=new rectSubClass(2,itemNo,3);
    }
    else if(lineStatus==1 && pathType==1)
    {
        rect1=new rectSubClass(1,noOfLines,1);

        rect2=new rectSubClass(2,noOfLines,1);
    }
    else if(lineStatus==2 && pathType==1)
    {
        rect1=new rectSubClass(1,itemNo,1);

        rect2=new rectSubClass(2,itemNo,1);
    }
    rect1->setPos((point0->x()),(point0->y()));
        connect(rect1,SIGNAL(abcd_xyz_moved(qreal,qreal,int,int,int)),this,SLOT(rect_moved_useful_2(qreal,qreal,int,int,int)));      
    rect2->setPos((point1->x()),(point1->y()));
        connect(rect2,SIGNAL(abcd_xyz_moved(qreal,qreal,int,int,int)),this,SLOT(rect_moved_useful_2(qreal,qreal,int,int,int)));
    myLineItem->addRectToMap(1,rect1);
    myLineItem->addRectToMap(2,rect2);
    qDebug()<<"rect count : "<<myLineItem->controlRectsCount()<<" linestatus "<<lineStatus;
    if(lineStatus==1 && pathType==3)
        orp_LineItems.insert(noOfLines,myLineItem);
    else if(lineStatus==2 && pathType==3)
        orp_LineItems.insert(itemNo,myLineItem);
    else if(lineStatus==1 && pathType==1)
        LinePathItems.insert(noOfLines,myLineItem);
    else if(lineStatus==2 && pathType==1)
        LinePathItems.insert(itemNo,myLineItem);
    qDebug()<<"no of orphn lines in map: "<<orp_LineItems.count();
    myScene->addItem(myLineItem);

}

void MainWindow::rectDrawing(QPoint *p0, QPoint *p1)
{
    Q_UNUSED (p0)
    Q_UNUSED (p1)
}

void MainWindow::bezierDrawing(QPoint *p0, QPoint *p1, QPoint *p2, QPoint *p3, int bezierStatus, int pathType,int itemNo)
{

    QPointF *point0=new QPointF(*p0);
    QPointF *point1=new QPointF(*p1);
    QPointF *point2=new QPointF(*p2);
    QPointF *point3=new QPointF(*p3);
    qDebug()<<"step 5";
    QPainterPath *path1=new QPainterPath;
    path1->moveTo(*point0);
    path1->cubicTo(*point1,*point2,*point3);
    if(bezierStatus==1)
    {
        noOfBeziers++;
        myBezierItem=new pathSubClass(*path1,noOfBeziers,pathType);
    }
    else if(bezierStatus==2)
    {
        myBezierItem=new pathSubClass(*path1,itemNo,pathType);
    }
    connect(myBezierItem,SIGNAL(addRectsToScene(int,int)),this,SLOT(slot_addRectsToScene(int,int)));
    connect(myBezierItem,SIGNAL(removeRectsFromScene(int,int)),this,SLOT(slot_removeRectsFromScene(int,int)));
    connect(myBezierItem,SIGNAL(addControlRectsToScene(int,int)),this,SLOT(slot_addControlRectsToScene(int,int)));
    connect(myBezierItem,SIGNAL(removeControlRectsToScene(int,int)),this,SLOT(slot_removeControlRectsFromScene(int,int)));
//    if(bezierStatus == 1)
//        myBezierItem->setPen(QPen(QColor(Qt::green),2));
//    else if(bezierStatus == 2)
//        myBezierItem->setPen(QPen(QColor(Qt::blue),2));
    qDebug()<<"step 6";
    rectSubClass *rect1, *rect2, *rectC1, *rectC2;
    if(bezierStatus==1 && pathType==2)
    {
         rect1=new rectSubClass(1,noOfBeziers,2);
         rectC1=new rectSubClass(2,noOfBeziers,2);
         rectC2=new rectSubClass(3,noOfBeziers,2);
         rect2=new rectSubClass(4,noOfBeziers,2);
    }
    else if(bezierStatus==2 && pathType==2)
    {
        rect1=new rectSubClass(1,itemNo,2);
        rectC1=new rectSubClass(2,itemNo,2);
        rectC2=new rectSubClass(3,itemNo,2);
        rect2=new rectSubClass(4,itemNo,2);
    }
    else if(bezierStatus==1 && pathType==4)
    {
        rect1=new rectSubClass(1,noOfBeziers,4);
        rectC1=new rectSubClass(2,noOfBeziers,4);
        rectC2=new rectSubClass(3,noOfBeziers,4);
        rect2=new rectSubClass(4,noOfBeziers,4);
    }
    else if(bezierStatus==2 && pathType==4)
    {
        rect1=new rectSubClass(1,itemNo,4);
        rectC1=new rectSubClass(2,itemNo,4);
        rectC2=new rectSubClass(3,itemNo,4);
        rect2=new rectSubClass(4,itemNo,4);
    }
    rect1->setPos(*point0);
    connect(rect1,SIGNAL(abcd_xyz_moved(qreal,qreal,int,int,int)),this,SLOT(rect_moved_useful_2(qreal,qreal,int,int,int)));
    rect2->setPos(*point3);
    connect(rect2,SIGNAL(abcd_xyz_moved(qreal,qreal,int,int,int)),this,SLOT(rect_moved_useful_2(qreal,qreal,int,int,int)));
    rectC1->setPos(*point1);
    connect(rectC1,SIGNAL(abcd_xyz_moved(qreal,qreal,int,int,int)),this,SLOT(rect_moved_useful_2(qreal,qreal,int,int,int)));
    rectC2->setPos(*point2);
    connect(rectC2,SIGNAL(abcd_xyz_moved(qreal,qreal,int,int,int)),this,SLOT(rect_moved_useful_2(qreal,qreal,int,int,int)));
    myBezierItem->addRectToMap(1,rect1);
    myBezierItem->addRectToMap(2,rectC1);
    myBezierItem->addRectToMap(3,rectC2);
    myBezierItem->addRectToMap(4,rect2);
    if(bezierStatus==1 && pathType==2)
        curvePathItems.insert(noOfBeziers,myBezierItem);
    else if(bezierStatus==2 && pathType==2)
        curvePathItems.insert(itemNo,myBezierItem);
    else if(bezierStatus==1 && pathType==4)
        orp_BezierItems.insert(noOfBeziers,myBezierItem);
    else if(bezierStatus==2 && pathType==4)
        orp_BezierItems.insert(itemNo,myBezierItem);
    qDebug()<<"step 7";
    qDebug()<<"rect count : "<<myBezierItem->controlRectsCount();
    myScene->addItem(myBezierItem);

    //--------------------------------------------------------------------------
    //--------------------------------------------------------------------------
}

void MainWindow::calIntersect()
{
    selItemList=myScene->selectedItems();
    int count=selItemList.count();
    qDebug()<<"inside calIntersect : sel count "<<count;
    if(count == 2)
    {

        pathSubClass *item1= dynamic_cast< pathSubClass(*)> (selItemList.at(0));
        pathSubClass *item2= dynamic_cast< pathSubClass(*)> (selItemList.at(1));
        qDebug()<<"if blk count == 2 : itemtype "<<item1->getItemType()<<" "<<item1->getIndexVal();
        if((item1->getItemType() == 1) && (item2->getItemType() == 1))
        {
            qDebug()<<"second if ... intersecting";
            myScene->removeItem(item1);
            myScene->removeItem(item1->getRectfromMap(1));
            myScene->removeItem(item1->getRectfromMap(2));
            item1->removeRect(1);
            item1->removeRect(2);
            myScene->removeItem(item2);
            myScene->removeItem(item2->getRectfromMap(1));
            myScene->removeItem(item2->getRectfromMap(2));
            item2->removeRect(1);
            item2->removeRect(2);
            noOfLines=noOfLines-2;
            intersectTwoLines(item1,item2);
        }
        else if((item1->getItemType() == 3) && (item2->getItemType() == 3))
        {
            myScene->removeItem(item1);
            myScene->removeItem(item1->getRectfromMap(1));
            myScene->removeItem(item1->getRectfromMap(2));
            item1->removeRect(1);
            item1->removeRect(2);
            myScene->removeItem(item2);
            myScene->removeItem(item1->getRectfromMap(1));
            myScene->removeItem(item1->getRectfromMap(2));
            item2->removeRect(1);
            item2->removeRect(2);
            noOfLines=noOfLines-2;
            intersectTwoLines(item1,item2);
        }
        else
        {
            qDebug()<<"item types do not match";
        }
    }
    else
    {
        qDebug()<<"else blk";

        qDebug()<<"Select 2 lines";
    }
}

void MainWindow::intersectTwoLines(pathSubClass *item1, pathSubClass *item2)
{
    int count=item1->path().elementCount();
    qDebug()<<count;
    QPointF *point1=new QPointF(item1->path().elementAt(0));
    QPointF *point2=new QPointF(item1->path().elementAt(1));
    QLine *tempLine1=new QLine((point1->x()),(point1->y()),(point2->x()),(point2->y()));

    count=item1->path().elementCount();
    QPointF *point3=new QPointF(item2->path().elementAt(0));
    QPointF *point4=new QPointF(item2->path().elementAt(1));
    QLine *tempLine2=new QLine((point3->x()),(point3->y()),(point4->x()),(point4->y()));

    QPointF *myIntersectPoint=new QPointF();
    qreal det, A1, A2, B1, B2, C1, C2;
    for(int i=0; i<(2-1); i++) //(noOfLines - 1)
    {
        A1 = tempLine1->y2() - tempLine1->y1();
        B1 = tempLine1->x1() - tempLine1->x2();
        C1 = A1*(tempLine1->x1()) + B1*(tempLine1->y1());
        A2 = tempLine2->y2() - tempLine2->y1();
        B2 = tempLine2->x1() - tempLine2->x2();
        C2 = A2*(tempLine2->x1()) + B2*(tempLine2->y1());

        det = A1*B2 - A2*B1;
        if(det == 0)
        {
               qDebug()<<"\nLines are parallel\n";
        }
        else
        {
            qreal x=(B2*C1 - B1*C2)/det;
             myIntersectPoint->setX(x);  // double x = (B2*C1 - B1*C2)/det
             qreal y= (A1*C2 - A2*C1)/det; //double y = (A1*C2 - A2*C1)/det
             myIntersectPoint->setY(y);
             qDebug()<<"myIntersectPoint: "<<myIntersectPoint->x()<<" "<<myIntersectPoint->y();
        }
    }



    double dist1= sqrt(((point1->x() - myIntersectPoint->x())*(point1->x() - myIntersectPoint->x())) + ((point1->y() - myIntersectPoint->y())*(point1->y() - myIntersectPoint->y())));
    double dist2= sqrt(((point2->x() - myIntersectPoint->x())*(point2->x() - myIntersectPoint->x())) + ((point2->y() - myIntersectPoint->y())*(point2->y() - myIntersectPoint->y())));
    if(dist1<dist2)
    {
        point1->setX(myIntersectPoint->x());
        point1->setY(myIntersectPoint->y());
    }
    else if(dist2<dist1)
    {
        point2->setX(myIntersectPoint->x());
        point2->setY(myIntersectPoint->y());
    }

    dist1=sqrt(((point3->x() - myIntersectPoint->x())*(point3->x() - myIntersectPoint->x())) + ((point3->y() - myIntersectPoint->y())*(point3->y() - myIntersectPoint->y())));
    dist2=sqrt(((point4->x() - myIntersectPoint->x())*(point4->x() - myIntersectPoint->x())) + ((point4->y() - myIntersectPoint->y())*(point4->y() - myIntersectPoint->y())));
    if(dist1<dist2)
    {
        point3->setX(myIntersectPoint->x());
        point3->setY(myIntersectPoint->y());
    }
    else if(dist2<dist1)
    {
        point4->setX(myIntersectPoint->x());
        point4->setY(myIntersectPoint->y());
    }

    QPoint *p1=new QPoint((point1->toPoint().x()),(point1->toPoint().y()));
    QPoint *p2=new QPoint((point2->toPoint().x()),(point2->toPoint().y()));
    QPoint *p3=new QPoint((point3->toPoint().x()),(point3->toPoint().y()));
    QPoint *p4=new QPoint((point4->toPoint().x()),(point4->toPoint().y()));

//    drawLine(p1,p2);
//    drawLine(p3,p4);
    /*
     *(a,b) (x,y)
     d=sqrt((a-x)^2 + (b-y)^2
     */
    lineDrawing(p1,p2,2,item1->getIndexVal(),item1->getItemType());
    lineDrawing(p3,p4,2,item2->getIndexVal(),item2->getItemType());

}

void MainWindow::calOffset()
{
    selItemList=myScene->selectedItems();
    int count=selItemList.count();
    double offset= (ui->lineEdit->text()).toDouble();
    if(!offset>0)
        offset=5.0;
    for(int i=0;i<count; i++)
    {
        pathSubClass *item1= dynamic_cast< pathSubClass(*)>(selItemList.at(i));
        if(item1->getItemType()==1)
        {
            qDebug()<<"item1->getItemType()==1";
            QPointF *point1=new QPointF(item1->path().elementAt(0));
            QPointF *point2=new QPointF(item1->path().elementAt(1));
            myScene->removeItem(item1);
            myScene->removeItem(item1->getRectfromMap(1));
            myScene->removeItem(item1->getRectfromMap(2));
            noOfLines=noOfLines-1;
            QLine line1=offsetPath(point1,point2,offset)->toLine();
            QPoint *p1=new QPoint((line1.p1().x()),(line1.p1().y()));
            QPoint *p2=new QPoint((line1.p2().x()),(line1.p2().y()));
            lineDrawing(p1,p2,2,item1->getIndexVal(),1);
        }
        else if(item1->getItemType()==3)
        {
            QPointF *point1=new QPointF(item1->path().elementAt(0));
            QPointF *point2=new QPointF(item1->path().elementAt(1));
            myScene->removeItem(item1);
            myScene->removeItem(item1->getRectfromMap(1));
            myScene->removeItem(item1->getRectfromMap(2));
            noOfLines=noOfLines-1;
            QLine line1=offsetPath(point1,point2,offset)->toLine();
            QPoint *p1=new QPoint((line1.p1().x()),(line1.p1().y()));
            QPoint *p2=new QPoint((line1.p2().x()),(line1.p2().y()));
            lineDrawing(p1,p2,2,item1->getIndexVal(),3);
        }
    }
}

QLineF *  MainWindow::offsetPath(QPointF *myp0, QPointF *myp1, double offset)
{
    //QPoint *returnPts1,*returnPts2;
    QLineF *line1=new QLineF();
    double d=offset;
    double dx2, dy2, mag, nx, ny;
    QPointF *p0=new QPointF(*myp0);
    QPointF *p1=new QPointF(*myp1);

    //calc part1
        dx2=p1->x() - p0->x();
        dy2=p1->y() - p0->y();
         mag= sqrt((dx2*dx2)+(dy2*dy2));

         if( fabs(mag) < 1.e-6 )
         {
             qDebug()<<"the magnitude is too small";
         }
         else
         {
            nx=(dy2/mag);
            ny=(-dx2/mag);
            qreal temp1=p0->x() + (d*nx);
            qreal temp2=p0->y() + (d*ny);
             offsetPoints[0]=new QPointF(temp1, temp2);
            //-----------------
            nx=(-dy2/mag);
            ny=(dx2/mag);
            temp1=p0->x() + (d*nx);
            temp2=p0->y() + (d*ny);
            offsetPoints[1]=new QPointF(temp1, temp2);

            qDebug()<<"run 1 "<<"pd: pdx : "<<offsetPoints[0]->x()<<" pdy : "<<offsetPoints[0]->y();
            qDebug()<<"run 1 "<<"pd: pdx : "<<offsetPoints[1]->x()<<" pdy : "<<offsetPoints[1]->y();
         }

    QPainterPath *myPath5=new QPainterPath(*offsetPoints[0]);
    line1->setP1(*offsetPoints[0]);
    //returnPts1=new QPoint((offsetPoints[0]->x()),(offsetPoints[0]->y()));
    //line1->setP1(*offsetPoints[0]); //for mypath5
   //calc part1 ends

   //calc part2
        dx2=p0->x() - p1->x();
        dy2=p0->y() - p1->y();
         mag= sqrt((dx2*dx2)+(dy2*dy2));

         if( fabs(mag) < 1.e-6 )
         {
             qDebug()<<"the magnitude is too small";
         }
         else
         {
            nx=(dy2/mag);
            ny=(-dx2/mag);
            qreal temp1=p1->x() + (d*nx);
            qreal temp2=p1->y() + (d*ny);
             offsetPoints[0]=new QPointF(temp1, temp2);
            //-----------------
            nx=(-dy2/mag);
            ny=(dx2/mag);
            temp1=p1->x() + (d*nx);
            temp2=p1->y() + (d*ny);
            offsetPoints[1]=new QPointF(temp1, temp2);

            qDebug()<<"run 2 "<<"pd: pdx : "<<offsetPoints[0]->x()<<" pdy : "<<offsetPoints[0]->y();
            qDebug()<<"run 2 "<<"pd: pdx : "<<offsetPoints[1]->x()<<" pdy : "<<offsetPoints[1]->y();
         }
    myPath5->lineTo(*offsetPoints[1]);
    line1->setP2(*offsetPoints[1]);// for mypath5
    //returnPts2=new QPoint((offsetPoints[1]->x()),(offsetPoints[1]->y()));
   // line1->setP2(*offsetPoints[1]);// for mypath5
   // myScene->addPath(*myPath5);
   //calc part2 ends
    //lineDrawing(returnPts1,returnPts2,2);
    //noOfLines=noOfLines+1;
    return line1;

}

void MainWindow::calBzrOffset()
{
    selItemList=myScene->selectedItems();
    int count=selItemList.count();
    double offset= (ui->lineEdit_2->text()).toDouble();
    if(!offset>0)
        offset=5.0;
    qDebug()<<"step 1";
    for(int i=0;i<count; i++)
    {
        pathSubClass *item1= dynamic_cast< pathSubClass(*)>(selItemList.at(i));
        qDebug()<<"step 2";
        if(item1->getItemType()==2)
        {
            qDebug()<<"step 3 : getItemType()==2";
            //int eleCount=item1->path().elementCount();
            myScene->removeItem(item1);
            myScene->removeItem(item1->getRectfromMap(1));
            myScene->removeItem(item1->getRectfromMap(4));
            myScene->removeItem(item1->getRectfromMap(2));
            myScene->removeItem(item1->getRectfromMap(3));
            noOfBeziers=noOfBeziers-1;
            QPointF *p1=new QPointF(item1->path().elementAt(0));
            QPointF *p2=new QPointF(item1->path().elementAt(1));
            QPointF *p3=new QPointF(item1->path().elementAt(2));
            QPointF *p4=new QPointF(item1->path().elementAt(3));
            linesArray[0]=new QLineF(*offsetPath(p1,p2,offset));
            linesArray[1]=new QLineF(*offsetPath(p2,p3,offset));
            linesArray[2]=new QLineF(*offsetPath(p3,p4,offset));
            calIntersectPointsForBzr();

            QPointF tempP1=linesArray[0]->p1();
            QPointF tempP4=linesArray[2]->p2();
            QPoint *pt1=new QPoint((tempP1.x()),(tempP1.y()));
            QPoint *pt4=new QPoint((tempP4.x()),(tempP4.y()));
            QPoint *pt2=new QPoint((intersectPoints[0]->toPoint().x()),(intersectPoints[0]->toPoint().y()));
            QPoint *pt3=new QPoint((intersectPoints[1]->toPoint().x()),(intersectPoints[1]->toPoint().y()));
            qDebug()<<"step 4";
            QString msg="Item no. "+QString::number(item1->getIndexVal())+" type 2 offseted by "+QString::number(offset)+" units";
            setStatusBarValues(msg,5000);
            bezierDrawing(pt1,pt2,pt3,pt4,2,2,item1->getIndexVal());
        }
        else if(item1->getItemType()==4)
        {
            qDebug()<<"step 3 : getItemType()==4";
            QPointF *p1=new QPointF(item1->path().elementAt(0));
            QPointF *p2=new QPointF(item1->path().elementAt(1));
            QPointF *p3=new QPointF(item1->path().elementAt(2));
            QPointF *p4=new QPointF(item1->path().elementAt(3));
            linesArray[0]=new QLineF(*offsetPath(p1,p2,offset));
            linesArray[1]=new QLineF(*offsetPath(p2,p3,offset));
            linesArray[2]=new QLineF(*offsetPath(p3,p4,offset));
            calIntersectPointsForBzr();

            QPointF tempP1=linesArray[0]->p1();
            QPointF tempP4=linesArray[2]->p2();
            QPoint *pt1=new QPoint((tempP1.x()),(tempP1.y()));
            QPoint *pt4=new QPoint((tempP4.x()),(tempP4.y()));
            QPoint *pt2=new QPoint((intersectPoints[0]->toPoint().x()),(intersectPoints[0]->toPoint().y()));
            QPoint *pt3=new QPoint((intersectPoints[1]->toPoint().x()),(intersectPoints[1]->toPoint().y()));
            qDebug()<<"step 4";
            QString msg="Item no. "+QString::number(item1->getIndexVal())+" type 4 offseted by "+QString::number(offset)+" units";
            setStatusBarValues(msg,5000);
            bezierDrawing(pt1,pt2,pt3,pt4,2,4,item1->getIndexVal());
        }
    }
}

void MainWindow::calIntersectPointsForBzr()
{
    QLineF *tempLine1;
    QLineF *tempLine2;
    QPointF *myIntersectPoint=new QPointF();
    qreal det, A1, A2, B1, B2, C1, C2;
    int i=0;
    for(i=0; i<(3-1); i++) //(3-1) for single cubic bezier curve
    {
        tempLine1=new QLineF(*linesArray[i]);
        tempLine2=new QLineF(*linesArray[i+1]);
        A1 = tempLine1->y2() - tempLine1->y1();
        B1 = tempLine1->x1() - tempLine1->x2();
        C1 = A1*(tempLine1->x1()) + B1*(tempLine1->y1());
        A2 = tempLine2->y2() - tempLine2->y1();
        B2 = tempLine2->x1() - tempLine2->x2();
        C2 = A2*(tempLine2->x1()) + B2*(tempLine2->y1());

        det = A1*B2 - A2*B1;
        if(det == 0)
        {
               qDebug()<<"\nLines are parallel\n";
        }
        else
        {
            qreal x=(B2*C1 - B1*C2)/det;
            myIntersectPoint->setX(x);  // double x = (B2*C1 - B1*C2)/det
            qreal y= (A1*C2 - A2*C1)/det; //double y = (A1*C2 - A2*C1)/det
            myIntersectPoint->setY(y);
            qDebug()<<"myIntersectPoint: "<<myIntersectPoint->x()<<" "<<myIntersectPoint->y();
            intersectPoints[i]=new QPointF(*myIntersectPoint);
        }
    }

    int j=0;
    qDebug()<<"after call intersect called "<<noOfLines;
//    for(j=0; j<(noOfLines-1); j++)
    for (j=0; j<(2);j++)
    {
        tempLine1=new QLineF(*linesArray[j]);
        tempLine1->setP2(*intersectPoints[j]);
        linesArray[j]=new QLineF(*tempLine1);
        qDebug()<<"after call intersect called";
        tempLine2=new QLineF(*linesArray[j+1]);
        tempLine2->setP1(*intersectPoints[j]);
        linesArray[j+1]=new QLineF(*tempLine2);
    }

}

void MainWindow::setStatusBarValues(QString msg, int timeOut)
{
    ui->statusBar->showMessage(msg,timeOut);
    ui->statusBar->setStatusTip("Last Operation: "+msg);
}

void MainWindow::on_actionDraw_line_triggered()
{
    ui->widget->startDrawing(true,1);
}

void MainWindow::on_actionDraw_cubic_bezier_triggered()
{
    ui->widget->startDrawing(true,3);
}

void MainWindow::on_actionIntersect_triggered()
{
    calIntersect();
}

void MainWindow::on_pushButton_2_clicked()
{
    myScene->clearSelection();
}

void MainWindow::on_pushButton_5_clicked()
{
    calOffset();
}

void MainWindow::on_actionUndo_remove_triggered()
{
    qDebug()<<"del count: "<<delItemMap.count();
    if(delCount>0)
    {
    pathSubClass *item=delItemMap.value(delCount);
    QPointF pos=delItemPosMap.value(delCount);
    delItemMap.remove(delCount);
    delItemPosMap.remove(delCount);
    delCount=delCount-1;
    if(item->getItemType() == 1)
        noOfLines=noOfLines+1;
    else if(item->getItemType() == 2)
        noOfBeziers=noOfBeziers+1;
    item->setPos((pos.x()),(pos.y()));
    myScene->addItem(item);
    myScene->addItem(item->getRectfromMap(1));
    if(item->getItemType()==1 || item->getItemType()==3)
    {
        myScene->addItem(item->getRectfromMap(2));
    }
    else if(item->getItemType()==2 || item->getItemType()==4)
    {
        myScene->addItem(item->getRectfromMap(4));
        myScene->addItem(item->getRectfromMap(2));
        myScene->addItem(item->getRectfromMap(3));
    }
    on_pushButton_2_clicked();
    }
}

void MainWindow::on_actionRemove_item_s_triggered()
{
    selItemList=myScene->selectedItems();
    int count=selItemList.count();
    for (int i=0; i<count; i++)
    {
        pathSubClass *item1= dynamic_cast< pathSubClass(*)> (selItemList.at(i));
        int type=item1->getItemType();
        if(type==1)
            --noOfLines;
        else if(type==2)
            --noOfBeziers;
        delCount=delCount+1;
        delItemMap.insert(delCount,item1);
        delItemPosMap.insert(delCount,item1->pos());
        myScene->removeItem(item1->getRectfromMap(1));
        if(item1->getItemType()==1 || item1->getItemType()==3)
        {
            myScene->removeItem(item1->getRectfromMap(2));
        }
        else if(item1->getItemType()==2 || item1->getItemType()==4)
        {
            myScene->removeItem(item1->getRectfromMap(4));
            myScene->removeItem(item1->getRectfromMap(2));
            myScene->removeItem(item1->getRectfromMap(3));
        }
        myScene->removeItem(item1);
    }
    QString msg= QString::number(delCount) + " items deleted." ;
    setStatusBarValues(msg,5000);
}

void MainWindow::on_actionItem_list_triggered()
{
    qDebug()<<"\nItem list";
    qDebug()<<"lines : "<<noOfLines;
    qDebug()<<"beziers : "<<noOfBeziers;
    QString msg="Items list "+"Lines : "+QString::number(noOfLines)+"  Beziers : "+QString::number(noOfBeziers);
    setStatusBarValues(msg,0);
}

void MainWindow::on_actionDraw_offset_bezier_triggered()
{
    calBzrOffset();
}

void MainWindow::on_actionNo_of_selected_Items_triggered()
{
    selItemList=myScene->selectedItems();
    qDebug()<<"no of selected items: "<<selItemList.count();
    QString msg="No of selected items: "+QString::number(selItemList.count());
    setStatusBarValues(msg,0);
}

void MainWindow::on_pushButton_clicked()
{
    calBzrOffset();
}

//-----------------------------------------------------------------------------------

void MainWindow::initiateFont()
{
    QString myfname="arial.ttf";
    myFont=new QRawFont(fontFileName,800,QFont::PreferFullHinting);
    qDebug()<<"myfont is valid: "<<myFont->isValid();
}

void MainWindow::initiateBasePath()
{
    quint32 myglyphindexes[3];
    int numofglyphs;
    myFont->glyphIndexesForChars(ui->lineEdit_3->text().constData(),ui->lineEdit_3->text().count(),myglyphindexes,&numofglyphs);
    qDebug()<<myglyphindexes[0]<<" "<<ui->lineEdit_3->text().constData()<<" "<<ui->lineEdit_3->text().count();
    basePath=myFont->pathForGlyph(myglyphindexes[0]);
    qDebug()<<"path is empty "<<basePath.isEmpty();
    myascent=myFont->ascent();
    qDebug()<<"ascent for font: "<<myFont->ascent();
    elementCount=basePath.elementCount();
}


void MainWindow::drawFont_function()
{
    qDebug()<<"start of drawFont_function()";
    basePath_1=new QPainterPath(basePath);
    drawFont_path=new QPainterPath;
    QPainterPath *drawFont_path1=new QPainterPath;

    QPainterPath *tempPath;
    pathSubClass *tempItem;

    int count, mapCurve=1,mapLine=1;
    int noOfPaths=0;
    int numbering=0;
    noOfControlRects=1;
    for(count=0;count<elementCount;)
    {
        const QPainterPath::Element & drawFont_element=basePath_1->elementAt(count);
        if(drawFont_element.isCurveTo())
        {

            for(int j=0;j<3;j++)
            {
               drawFont_points[count+j]=new QPointF(basePath_1->elementAt(count+j));
               temp_points[count+j]=new QPointF(((drawFont_points[count+j])->x()),((drawFont_points[count+j]->y())+(myascent)));
            }
            noOfBeziers=noOfBeziers+1;
            drawFont_path1->cubicTo(*temp_points[count+0],*temp_points[count+1],*temp_points[count+2]);            
                            tempPath=new QPainterPath(*temp_points[count-1]);
                            tempPath->cubicTo(*temp_points[count+0],*temp_points[count+1],*temp_points[count+2]);
                            tempItem=new pathSubClass(*tempPath,noOfBeziers,2);
                            connect(tempItem,SIGNAL(addRectsToScene(int,int)),this,SLOT(slot_addRectsToScene(int,int)));
                            connect(tempItem,SIGNAL(removeRectsFromScene(int,int)),this,SLOT(slot_removeRectsFromScene(int,int)));
                            connect(tempItem,SIGNAL(addControlRectsToScene(int,int)),this,SLOT(slot_addControlRectsToScene(int,int)));
                            connect(tempItem,SIGNAL(removeControlRectsToScene(int,int)),this,SLOT(slot_removeControlRectsFromScene(int,int)));
                            drawControlPoints(temp_points[count-1],temp_points[count+2],temp_points[count],temp_points[count+1],tempItem,noOfBeziers,2);
                            curvePathItems.insert(noOfBeziers,tempItem);
                            mapCurve=mapCurve+1;
                            allPathItems.insert(count,tempItem);
            controlPoints[numbering++]=new QPointF(*temp_points[count+2]);
            count=count+3;
        }
        else if(drawFont_element.isLineTo())
        {

            drawFont_points[count]=new QPointF(basePath_1->elementAt(count));
            temp_points[count]=new QPointF(((drawFont_points[count])->x()),((drawFont_points[count]->y())+(myascent)));
            drawFont_path1->lineTo(*temp_points[count]);
            noOfLines=noOfLines+1;
                            tempPath=new QPainterPath(*temp_points[count-1]);
                            tempPath->lineTo(*temp_points[count]);
                            tempItem=new pathSubClass(*tempPath,noOfLines,1);
                            connect(tempItem,SIGNAL(addRectsToScene(int,int)),this,SLOT(slot_addRectsToScene(int,int)));
                            connect(tempItem,SIGNAL(removeRectsFromScene(int,int)),this,SLOT(slot_removeRectsFromScene(int,int)));
                            drawControlPoints(temp_points[count-1],temp_points[count],(new QPointF(10,10)),(new QPointF(10,10)),tempItem,noOfLines,1);
                            LinePathItems.insert(noOfLines,tempItem);
                            mapLine=mapLine+1;
                            allPathItems.insert(count,tempItem);
            controlPoints[numbering++]=new QPointF(*temp_points[count]);
            count=count+1;
        }
        else if(drawFont_element.isMoveTo())
        {
            drawFont_points[count]=new QPointF(basePath_1->elementAt(count));
            temp_points[count]=new QPointF(((drawFont_points[count])->x()),((drawFont_points[count]->y())+(myascent)));
            drawFont_path1->moveTo(*temp_points[count]);
            controlPoints[numbering++]=new QPointF(*temp_points[count]);
            count=count+1;
        }
    }
    //------------------------------
    arrOfPath[noOfPaths]=new QPainterPath(*drawFont_path1);
    arrOfPathItems[noOfPaths]=new pathSubClass(*drawFont_path1,(noOfPaths+1));
    noOfPaths=noOfPaths+1;
    QMap<int, pathSubClass*>::iterator i2;
    for(i2=curvePathItems.begin(); i2!=curvePathItems.end(); i2++)
    {
        myScene->addItem(i2.value());
    }

    for(i2=LinePathItems.begin(); i2!=LinePathItems.end(); i2++)
    {
        myScene->addItem(i2.value());
    }
    noOfControlPoints=numbering;
    QString msg="Character "+ui->lineEdit_3->text()+" drawn.";
    setStatusBarValues(msg,5000);
}

void MainWindow::drawControlPoints(QPointF *point1, QPointF *point2,QPointF *pointC1,QPointF *pointC2,pathSubClass *item1, int pathNo, int pathType)
{
    rectSubClass *myrect=new rectSubClass(1,pathNo,pathType);
    myrect->setPos(*point1);
    item1->addRectToMap(1,myrect);
    connect(myrect,SIGNAL(abcd_xyz_moved(qreal,qreal,int,int,int)),this,SLOT(rect_moved_useful_2(qreal,qreal,int,int,int)));

    rectSubClass *myrect2=new rectSubClass(4,pathNo,pathType);
    myrect2->setPos(*point2);
    item1->addRectToMap(4,myrect2);
    connect(myrect2,SIGNAL(abcd_xyz_moved(qreal,qreal,int,int,int)),this,SLOT(rect_moved_useful_2(qreal,qreal,int,int,int)));

    rectSubClass *myrectC1=new rectSubClass(2,pathNo,pathType);
     myrectC1->setPos(*pointC1);
      item1->addRectToMap(2,myrectC1);
    connect(myrectC1,SIGNAL(abcd_xyz_moved(qreal,qreal,int,int,int)),this,SLOT(rect_moved_useful_2(qreal,qreal,int,int,int)));

    rectSubClass *myrectC2=new rectSubClass(3,pathNo,pathType);
     myrectC1->setPos(*pointC2);
      item1->addRectToMap(3,myrectC2);
    connect(myrectC2,SIGNAL(abcd_xyz_moved(qreal,qreal,int,int,int)),this,SLOT(rect_moved_useful_2(qreal,qreal,int,int,int)));
//    controlRects.insert(noOfControlRects,myrect);
//    controlRects.insert(noOfControlRects+1,myrect2);
//    noOfControlRects=noOfControlRects+2;
}

void MainWindow::redrawControlPoints(qreal xCord, qreal yCord, int index, int pathNo, int pathType)
{
    pathSubClass *tempItem;
    rectSubClass *rectItem;
    if((pathType == 1) && (pathNo != 777))
    {
        tempItem=LinePathItems.value(pathNo);
        rectItem=tempItem->getRectfromMap(index);
        qreal xPos=rectItem->pos().x();
        qreal yPos=rectItem->pos().y();
        rectItem->setPos((xPos + xCord),yPos + yCord);
        //-----------------------updating the paths
        QPainterPath *path1=new QPainterPath(tempItem->path());
        if(index==1)
        {
            QPointF *p1=new QPointF(path1->elementAt(0));
            QPointF *p2=new QPointF(path1->elementAt(1));
            qreal newX=p1->x()+xCord;
            qreal newY=p1->y()+yCord;
            p1=new QPointF(newX,newY);
            QPainterPath *newPath=new QPainterPath;
            newPath->moveTo(*p1);
            newPath->lineTo(*p2);
            tempItem->setPath(*newPath);
        }
        else if(index==2)
        {
            QPointF *p1=new QPointF(path1->elementAt(0));
            QPointF *p2=new QPointF(path1->elementAt(1));
            qDebug()<<"items's p1 : "<<p1->x()<<" "<<p1->y();
            qDebug()<<"items's p2 : "<<p2->x()<<" "<<p2->y();
            qreal newX=p2->x()+xCord;
            qreal newY=p2->y()+yCord;
            p2=new QPointF(newX,newY);
            qDebug()<<"items's new p2 : "<<p2->x()<<" "<<p2->y();
            QPainterPath *newPath=new QPainterPath;
            newPath->moveTo(*p1);
            newPath->lineTo(*p2);
            tempItem->setPath(*newPath);
        }

    }
    else if(pathType == 2)
    {
        qDebug()<<"pathType==3";
        tempItem=curvePathItems.value(pathNo);
        rectItem=tempItem->getRectfromMap(index);
        qreal xPos=rectItem->pos().x();
        qreal yPos=rectItem->pos().y();
        rectItem->setPos((xPos + xCord),yPos + yCord);
        //-----------------------updating the paths
        QPainterPath *path1=new QPainterPath(tempItem->path());
        if(index==1)
        {
            QPointF *p1=new QPointF(path1->elementAt(0));
            QPointF *p2=new QPointF(path1->elementAt(1));
            QPointF *p3=new QPointF(path1->elementAt(2));
            QPointF *p4=new QPointF(path1->elementAt(3));
            qreal newX=p1->x()+xCord;
            qreal newY=p1->y()+yCord;
            p1=new QPointF(newX,newY);
            QPainterPath *newPath=new QPainterPath;
            newPath->moveTo(*p1);
            newPath->cubicTo(*p2,*p3,*p4);
            tempItem->setPath(*newPath);
        }
        else if(index==4)
        {
            QPointF *p1=new QPointF(path1->elementAt(0));
            QPointF *p2=new QPointF(path1->elementAt(1));
            QPointF *p3=new QPointF(path1->elementAt(2));
            QPointF *p4=new QPointF(path1->elementAt(3));
            qreal newX=p4->x()+xCord;
            qreal newY=p4->y()+yCord;
            p4=new QPointF(newX,newY);
            QPainterPath *newPath=new QPainterPath;
            newPath->moveTo(*p1);
            newPath->cubicTo(*p2,*p3,*p4);
            tempItem->setPath(*newPath);
        }
        else if(index==2)
        {
            QPointF *p1=new QPointF(path1->elementAt(0));
            QPointF *p2=new QPointF(path1->elementAt(1));
            QPointF *p3=new QPointF(path1->elementAt(2));
            QPointF *p4=new QPointF(path1->elementAt(3));
            qreal newX=p2->x()+xCord;
            qreal newY=p2->y()+yCord;
            p2=new QPointF(newX,newY);
            QPainterPath *newPath=new QPainterPath;
            newPath->moveTo(*p1);
            newPath->cubicTo(*p2,*p3,*p4);
            tempItem->setPath(*newPath);
        }
        else if(index==3)
        {
            QPointF *p1=new QPointF(path1->elementAt(0));
            QPointF *p2=new QPointF(path1->elementAt(1));
            QPointF *p3=new QPointF(path1->elementAt(2));
            QPointF *p4=new QPointF(path1->elementAt(3));
            qreal newX=p3->x()+xCord;
            qreal newY=p3->y()+yCord;
            p3=new QPointF(newX,newY);
            QPainterPath *newPath=new QPainterPath;
            newPath->moveTo(*p1);
            newPath->cubicTo(*p2,*p3,*p4);
            tempItem->setPath(*newPath);
        }
    }

    else if(pathType==3)
    {
        qDebug()<<"pathType==3";
        tempItem=orp_LineItems.value(pathNo);
        rectItem=tempItem->getRectfromMap(index);
        qreal xPos=rectItem->pos().x();
        qreal yPos=rectItem->pos().y();
        rectItem->setPos((xPos + xCord),yPos + yCord);
        //-----------------------updating the paths
        QPainterPath *path1=new QPainterPath(tempItem->path());
        if(index==1)
        {
            QPointF *p1=new QPointF(path1->elementAt(0));
            QPointF *p2=new QPointF(path1->elementAt(1));
            qreal newX=p1->x()+xCord;
            qreal newY=p1->y()+yCord;
            p1=new QPointF(newX,newY);
            QPainterPath *newPath=new QPainterPath;
            newPath->moveTo(*p1);
            newPath->lineTo(*p2);
            tempItem->setPath(*newPath);
        }
        else if(index==2)
        {
            QPointF *p1=new QPointF(path1->elementAt(0));
            QPointF *p2=new QPointF(path1->elementAt(1));
            qDebug()<<"items's p1 : "<<p1->x()<<" "<<p1->y();
            qDebug()<<"items's p2 : "<<p2->x()<<" "<<p2->y();
            qreal newX=p2->x()+xCord;
            qreal newY=p2->y()+yCord;
            p2=new QPointF(newX,newY);
            qDebug()<<"items's new p2 : "<<p2->x()<<" "<<p2->y();
            QPainterPath *newPath=new QPainterPath;
            newPath->moveTo(*p1);
            newPath->lineTo(*p2);
            tempItem->setPath(*newPath);
        }
    }
    else if(pathType==4)
    {
        qDebug()<<"pathType==4";
        tempItem=orp_BezierItems.value(pathNo);
        rectItem=tempItem->getRectfromMap(index);
        qreal xPos=rectItem->pos().x();
        qreal yPos=rectItem->pos().y();
        rectItem->setPos((xPos + xCord),yPos + yCord);
        //-----------------------updating the paths
        QPainterPath *path1=new QPainterPath(tempItem->path());
        if(index==1)
        {
            QPointF *p1=new QPointF(path1->elementAt(0));
            QPointF *p2=new QPointF(path1->elementAt(1));
            QPointF *p3=new QPointF(path1->elementAt(2));
            QPointF *p4=new QPointF(path1->elementAt(3));
            qreal newX=p1->x()+xCord;
            qreal newY=p1->y()+yCord;
            p1=new QPointF(newX,newY);
            QPainterPath *newPath=new QPainterPath;
            newPath->moveTo(*p1);
            newPath->cubicTo(*p2,*p3,*p4);
            tempItem->setPath(*newPath);
        }
        else if(index==4)
        {
            QPointF *p1=new QPointF(path1->elementAt(0));
            QPointF *p2=new QPointF(path1->elementAt(1));
            QPointF *p3=new QPointF(path1->elementAt(2));
            QPointF *p4=new QPointF(path1->elementAt(3));
            qreal newX=p4->x()+xCord;
            qreal newY=p4->y()+yCord;
            p4=new QPointF(newX,newY);
            QPainterPath *newPath=new QPainterPath;
            newPath->moveTo(*p1);
            newPath->cubicTo(*p2,*p3,*p4);
            tempItem->setPath(*newPath);
        }
        else if(index==2)
        {
            QPointF *p1=new QPointF(path1->elementAt(0));
            QPointF *p2=new QPointF(path1->elementAt(1));
            QPointF *p3=new QPointF(path1->elementAt(2));
            QPointF *p4=new QPointF(path1->elementAt(3));
            qreal newX=p2->x()+xCord;
            qreal newY=p2->y()+yCord;
            p2=new QPointF(newX,newY);
            QPainterPath *newPath=new QPainterPath;
            newPath->moveTo(*p1);
            newPath->cubicTo(*p2,*p3,*p4);
            tempItem->setPath(*newPath);
        }
        else if(index==3)
        {
            QPointF *p1=new QPointF(path1->elementAt(0));
            QPointF *p2=new QPointF(path1->elementAt(1));
            QPointF *p3=new QPointF(path1->elementAt(2));
            QPointF *p4=new QPointF(path1->elementAt(3));
            qreal newX=p3->x()+xCord;
            qreal newY=p3->y()+yCord;
            p3=new QPointF(newX,newY);
            QPainterPath *newPath=new QPainterPath;
            newPath->moveTo(*p1);
            newPath->cubicTo(*p2,*p3,*p4);
            tempItem->setPath(*newPath);
        }
    }
}

void MainWindow::saveImageAsPng()
{
    myScene->clearSelection();                                                  // Selections would also render to the file
    myScene->setSceneRect(myScene->itemsBoundingRect());                          // Re-shrink the scene to it's bounding contents
    QImage myImage(myScene->sceneRect().size().toSize(), QImage::Format_ARGB32);  // Create the image with the exact size of the shrunk scene
    myImage.fill(Qt::transparent);                                              // Start all pixels transparent

    QPainter painter(&myImage);
    myScene->render(&painter);
    QString lmnopqr=QFileDialog ::getSaveFileName(this,tr("Save Current DRawing"),
                                                   tr("PNG files(*.png)"));
    bool isSaved=false;
//    QStringList stringhh;
//    QString myStr="";
    if(lmnopqr!="")
    {
//      //  isSaved=myImage.save(lmnopqr);
////         isSaved=myImage.save("C://Relesefile_name2.png");
//    stringhh=lmnopqr.split("/");
//    int count=stringhh.count();

//    for(int i=0; i<count; i++)
//    {
//        QString tempStr=stringhh.at(i);
//        if(i==0)
//        {
//            myStr=myStr+tempStr+"//";
//        }
//        else if(i==(count-1))
//        {
//            myStr=myStr+tempStr;
//        }
//        else
//            myStr=myStr+tempStr+"/";

//    }
        isSaved=myImage.save(lmnopqr);
    }

    if(isSaved)
    {

        qDebug()<<"file saved successfully";
        QString msg="file saved successfully";
        setStatusBarValues(msg,5000);
    }
    else
    {
        qDebug()<<"Error saving file "<<lmnopqr;
        QString msg="Error saving file....";
        setStatusBarValues(msg,5000);
    }
}

void MainWindow::scaleMyCurve(pathSubClass *item1, double value)
{
//    pathSubClass *tempItem=new pathSubClass();
//    tempItem=item1;
    QPainterPath *tempPath=new QPainterPath(item1->path());
    QPointF *p0=new QPointF(tempPath->elementAt(0));
    QPointF *p1=new QPointF(tempPath->elementAt(1));
    QPointF *p2=new QPointF(tempPath->elementAt(2));
    QPointF *p3=new QPointF(tempPath->elementAt(3));

    QPointF *ps0=new QPointF((p0->x()*value),(p0->y()*value));
    QPointF *ps1=new QPointF((p1->x()*value),(p1->y()*value));
    QPointF *ps2=new QPointF((p2->x()*value),(p2->y()*value));
    QPointF *ps3=new QPointF((p3->x()*value),(p3->y()*value));

    QPoint *t0=new QPoint((ps0->x()),(ps0->y()));
    QPoint *t1=new QPoint((ps1->x()),(ps1->y()));
    QPoint *t2=new QPoint((ps2->x()),(ps2->y()));
    QPoint *t3=new QPoint((ps3->x()),(ps3->y()));

    tempPath=new QPainterPath(*ps0);
    tempPath->cubicTo((t1->x()),(t1->y()),(t2->x()),(t2->y()),(t3->x()),(t3->y()));
    rectSubClass *rect1=item1->getRectfromMap(1);
    rectSubClass *rect2=item1->getRectfromMap(4);
    rectSubClass *rectC1=item1->getRectfromMap(2);
    rectSubClass *rectC2=item1->getRectfromMap(3);
    rect1->setPos((t0->x()),(t0->y()));
    rect2->setPos((t3->x()),(t3->y()));
    rectC1->setPos((t1->x()),(t1->y()));
    rectC2->setPos((t2->x()),(t2->y()));

    item1->addRectToMap(1,rect1);
    item1->addRectToMap(4,rect2);
    item1->addRectToMap(2,rectC1);
    item1->addRectToMap(3,rectC2);
    item1->setPen(QPen(QColor(Qt::red)));
    item1->setPath(*tempPath);
}

void MainWindow::showPointArray(QPointF *myArray[])
{
    qDebug()<<"\n";
    for(int i=0; i<elementCount; i++)
    {
        qDebug()<<"element : "<<i<<" : "<<myArray[i]->x()<<" "<<myArray[i]->y();
    }
    qDebug()<<"\n";
}


void MainWindow::on_pushButton_3_clicked()
{
    initiateFont();
    initiateBasePath();
    drawFont_function();
}

void MainWindow::on_pushButton_4_clicked()
{
//    int count=controlRects.count();
//    qDebug()<<"count "<<count;
//    QMap<int, rectSubClass*>::iterator i;
//    for (i = controlRects.begin(); i != controlRects.end(); ++i)
//    {
//        qDebug()<<i.key()<<" "<<i.value()->pos();
//    }
}

void MainWindow::setControlRects()
{
    int mapCount=controlRects.count();
    for(int i=3; i<=mapCount;)
    {
        QPointF p1=controlRects.value(i)->pos();
        QPointF p2=controlRects.value(i-1)->pos();
        if((p1.x() == p2.x()) && (p1.y() == p2.y()))
        {
            controlRects.remove(i);
            i++;
        }
        i++;
    }
}

void MainWindow::on_pushButton_6_clicked()
{
//    setControlRects();

}

void MainWindow::on_pushButton_7_clicked()
{
    QList<QGraphicsItem* >listabc=myScene->items();
    qDebug()<<"listabc.count() "<<listabc.count();
//    for(int i; i<listabc.count(); i++)
//    {
//        QGraphicsItem *delItem=listabc.at(i);
//        //myScene->removeItem(delItem);
//        delete delItem;
//    }
    myScene->clear();
    noOfBeziers=0;
    noOfLines=0;
    orp_LineItems.clear();
    orp_BezierItems.clear();
    LinePathItems.clear();
    curvePathItems.clear();
    allPathItems.clear();
    controlRects.clear();
    delItemMap.clear();
    delItemPosMap.clear();
}

void MainWindow::on_actionOpen_Font_triggered()
{
    QString fileName = QFileDialog::getOpenFileName(this,
    tr("Open Font"), "/home", tr("Font Files (*.ttf)"));
    if(fileName != "")
    {
        fontFileName=fileName;
    }
}

void MainWindow::on_actionPNG_file_triggered()
{
    saveImageAsPng();
}

void MainWindow::on_pushButton_8_clicked()
{
    QList<QGraphicsItem* > selList=myScene->selectedItems();
    int count=selList.count();
    if(count==2)
    {
        pathSubClass *item1= dynamic_cast<pathSubClass*> (selList.at(0));
        pathSubClass *item2= dynamic_cast<pathSubClass*> (selList.at(1));
        if((item1->getItemType()==4) && (item2->getItemType() == 4))
        {
            pathSubClass *temp1=orp_BezierItems.value(item1->getIndexVal());
            QPainterPath *tempPath=new QPainterPath(temp1->path());
            QPointF *p0=new QPointF(tempPath->elementAt(0));
            QPointF *p1=new QPointF(tempPath->elementAt(1));
            QPointF *p2=new QPointF(tempPath->elementAt(2));
            QPointF *B1=new QPointF;
            qreal x=(2*p2->x()) - (p1->x());
            qreal y=(2*p2->y()) - (p1->y());
            B1->setX((x));
            B1->setY((y));

//            pathSubClass *temp2=orp_BezierItems.value(item2->getIndexVal());
//            tempPath=new QPainterPath(temp2->path());
//            QPointF *c0=new QPointF(tempPath->elementAt(0));
//            QPointF *c1=new QPointF(tempPath->elementAt(1));
//            QPointF *c2=new QPointF(tempPath->elementAt(2));
//            QPointF *B2=new QPointF;
//            x=(2*c0->x()) - (c1->x());
//            y=(2*c0->y()) - (c1->y());
//            B2->setX((x));
//            B2->setY((y));
            pathSubClass *temp2=orp_BezierItems.value(item2->getIndexVal());
            tempPath=new QPainterPath(temp2->path());
             QPointF *c0=new QPointF(tempPath->elementAt(3));
             QPointF *c1=new QPointF(tempPath->elementAt(2));
             QPointF *c2=new QPointF(tempPath->elementAt(1));
                         QPointF *B2=new QPointF;
                         x=(2*c0->x()) - (c1->x());
                         y=(2*c0->y()) - (c1->y());
                         B2->setX((x));
                         B2->setY((y));
            QPointF *p4=new QPointF(tempPath->elementAt(0));
            //which are to be used po, B1, B2, p4
            //----------------------creating new curve
            orp_BezierItems.remove(item1->getIndexVal());
            orp_BezierItems.remove(item2->getIndexVal());
            myScene->removeItem(item1);
            myScene->removeItem(item1->getRectfromMap(1));
            myScene->removeItem(item1->getRectfromMap(4));
            myScene->removeItem(item1->getRectfromMap(2));
            myScene->removeItem(item1->getRectfromMap(3));
            myScene->removeItem(item2);
            myScene->removeItem(item2->getRectfromMap(1));
            myScene->removeItem(item2->getRectfromMap(4));
            myScene->removeItem(item2->getRectfromMap(2));
            myScene->removeItem(item2->getRectfromMap(3));
            noOfBeziers=noOfBeziers-2;
            //----------------------------------
            QPoint *mid1=new QPoint;
            mid1->setX(((p1->x()+p2->x())/2));
            mid1->setY(((p1->y()+p2->y())/2));
            QPoint *mid2=new QPoint;
            mid2->setX(((c1->x()+c2->x())/2));
            mid2->setX(((c1->y()+c2->y())/2));
            //----------------------------------
            QPoint *t1=new QPoint((p0->x()),(p0->y()));
            QPoint *t2=new QPoint((B1->x()),(B1->y()));
            QPoint *t3=new QPoint((B2->x()),(B2->y()));
            QPoint *t4=new QPoint((p4->x()),(p4->y()));

            QPainterPath *myAsdd=new QPainterPath(*p0);
            myAsdd->cubicTo(*B1,*B2,*p4);
            pathSubClass *iijhh=new pathSubClass(*myAsdd,8888);
            //iijhh->setPen(QPen(QColor(Qt::red)));
            myScene->addItem(iijhh);
            //myScene->addPath(*myAsdd);
//            bezierDrawing(t1,t2,t3,t4,1,4,999);
//            bezierDrawing(t1,t2,t3,t4,1,4,999);
//            bezierDrawing(t1,mid1,mid2,t2,1,4,999);
        }
       else if((item1->getItemType()==2) && (item2->getItemType() == 2))
        {
            pathSubClass *temp1=curvePathItems.value(item1->getIndexVal());
                        QPainterPath *tempPath=new QPainterPath(temp1->path());
                        QPointF *p0=new QPointF(tempPath->elementAt(0));
                        QPointF *p1=new QPointF(tempPath->elementAt(1));
                        QPointF *p2=new QPointF(tempPath->elementAt(2));
                        QPointF *p41=new QPointF(tempPath->elementAt(3));
                        QPointF *B1=new QPointF;
//                        qreal x=(2*p2->x()) - (p1->x());
//                        qreal y=(2*p2->y()) - (p1->y());
//                        B1->setX((x));
//                        B1->setY((y));
                        qreal x=(2*p0->x())-(p1->x());
                        qreal y=(2*p0->y())-(p1->y());
                        B1->setX((x));
                        B1->setY((y));
                                    pathSubClass *temp2=curvePathItems.value(item2->getIndexVal());
                                    tempPath=new QPainterPath(temp2->path());
                                    QPointF *c0=new QPointF(tempPath->elementAt(0));
                                    QPointF *c1=new QPointF(tempPath->elementAt(1));
                                    QPointF *c2=new QPointF(tempPath->elementAt(2));
                                    QPointF *p42=new QPointF(tempPath->elementAt(3));
                                    QPointF *B2=new QPointF;
//                                    x=(2*c0->x()) - (c1->x());
//                                    y=(2*c0->y()) - (c1->y());
//                                    B2->setX((x));
//                                    B2->setY((y));
                                    x=(2*c1->x()) - (c2->x());
                                    y=(2*c1->y()) - (c2->y());
                                    B2->setX((x));
                                    B2->setY((y));
                                    curvePathItems.remove(item1->getIndexVal());
                                                curvePathItems.remove(item2->getIndexVal());
                                                myScene->removeItem(item1);
                                                myScene->removeItem(item1->getRectfromMap(1));
                                                myScene->removeItem(item1->getRectfromMap(4));
                                                myScene->removeItem(item1->getRectfromMap(2));
                                                myScene->removeItem(item1->getRectfromMap(3));
                                                myScene->removeItem(item2);
                                                myScene->removeItem(item2->getRectfromMap(1));
                                                myScene->removeItem(item2->getRectfromMap(4));
                                                myScene->removeItem(item2->getRectfromMap(2));
                                                myScene->removeItem(item2->getRectfromMap(3));
                                                noOfBeziers=noOfBeziers-2;
                                                qDebug()<<"step 3";
                           QPoint *t1=new QPoint((p41->x()),(p41->y()));
                           QPoint *t2=new QPoint((B1->x()),(B1->y()));
                          QPoint *t3=new QPoint((B2->x()),(B2->y()));
                           QPoint *t4=new QPoint((p42->x()),(p42->y()));

                          QPainterPath *myAsdd=new QPainterPath(*t1);
                            myAsdd->cubicTo(*t2,*t3,*t4);
                           pathSubClass *iijhh=new pathSubClass(*myAsdd,8888);
                           //iijhh->setPen(QPen(QColor(Qt::red)));
//                            myScene->addItem(iijhh);

                           bezierDrawing(t1,t2,t3,t4,1,2,999);

        }
    }
}



/*

    QPainterPath *path2=new QPainterPath(*p1);
    path2->lineTo(*p4);
     myScene->addPath(*path2);

    QPainterPath *path3=new QPainterPath(*p1);
    path3->lineTo(*p2);
//    path3->lineTo(*p4);
//    path3->lineTo(*p3);
//    path3->lineTo(*p1);
    myScene->addPath(*path3);

    //dist btw p1 and c1
    double dist1=sqrt(((p2->x() - p1->x())*(p2->x() - p1->x())) + ((p2->y() - p1->y())*(p2->y() - p1->y())));
    qDebug()<<"dist1 "<<dist1;
    qreal val=QPointF::dotProduct(*p1,*p2);
    qDebug()<<"val: "<<val;

    //dist btw p4 and c2
    double dist2=sqrt(((p4->x() - p3->x())*(p4->x() - p3->x())) + ((p4->y() - p3->y())*(p4->y() - p3->y())));
    qDebug()<<"dist2 "<<dist2;
    val=QPointF::dotProduct(*p3,*p4);
    qDebug()<<"val: "<<val;
    val=QPointF::dotProduct(*p4,*p3);
    qDebug()<<"val: "<<val;

 */

void MainWindow::on_pushButton_9_clicked()
{
    QList<QGraphicsItem* >selList2=myScene->selectedItems();
    double value= ui->lineEdit_4->text().toDouble(); // scale factor
    for(int i=0; i<selList2.count(); i++)
    {
        pathSubClass *tempItem= dynamic_cast<pathSubClass* > (selList2.at(i));
        if(tempItem->getItemType()==2)
        {
//            qDebug()<<"item1->getItemType()==2";
//            QPainterPath *tempPath=new QPainterPath(tempItem->path());
//            QPointF *p0=new QPointF(tempPath->elementAt(0));
//            QPointF *p1=new QPointF(tempPath->elementAt(1));
//            QPointF *p2=new QPointF(tempPath->elementAt(2));
//            QPointF *p3=new QPointF(tempPath->elementAt(3));

//            QPointF *ps0=new QPointF((p0->x()*value),(p0->y()*value));
//            QPointF *ps1=new QPointF((p1->x()*value),(p1->y()*value));
//            QPointF *ps2=new QPointF((p2->x()*value),(p2->y()*value));
//            QPointF *ps3=new QPointF((p3->x()*value),(p3->y()*value));

//            QPoint *t0=new QPoint((ps0->x()),(ps0->y()));
//            QPoint *t1=new QPoint((ps1->x()),(ps1->y()));
//            QPoint *t2=new QPoint((ps2->x()),(ps2->y()));
//            QPoint *t3=new QPoint((ps3->x()),(ps3->y()));
//            noOfBeziers=noOfBeziers-1;
//            bezierDrawing(t0,t1,t2,t3,2,2,tempItem->getIndexVal());
            scaleMyCurve(tempItem,value);
        }
    }
}

void MainWindow::on_actionShow_Grid_triggered()
{
    myScene->setDrawGrid(true);
    myScene->update();
}
